home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <GL/glx.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <X11/keysym.h>
-
- static int RGB_SB_attributes[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- static int RGB_DB_attributes[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- static int CI_SB_attributes[] = {
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- static int CI_DB_attributes[] = {
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- #define SETCOLOR(x) if (rgb) glColor3fv(rgbMap[x]); else glIndexf(x)
-
- enum {
- BLACK = 0,
- RED,
- GREEN,
- YELLOW,
- BLUE,
- MAGENTA,
- CYAN,
- WHITE
- };
-
- #define COLOR_OFFSET 16
-
- static float rgbMap[8][3] = {
- {0, 0, 0},
- {1, 0, 0},
- {0, 1, 0},
- {1, 1, 0},
- {0, 0, 1},
- {1, 0, 1},
- {0, 1, 1},
- {1, 1, 1}
- };
-
- Display *dpy;
- Colormap cmap;
- Window window;
- int rgb = 1;
- int doubleBuf = 1;
- int W = 300;
- int H = 300;
-
- static GLint indexBits;
- static long ci = YELLOW;
- static GLboolean dither = GL_TRUE;
- static GLboolean fragment = GL_FALSE;
- static GLboolean smoothModel = GL_TRUE;
- static long mode1, mode2;
- static int blending;
- static float size;
- static float pntA[3] = {-165, 0, -0.5};
- static float pntB[3] = {-60, 0, -0.5};
- static float pntC[3] = {-40, -50, -0.5};
- static float pntD[3] = {30, 60, -0.5};
- static float pntAAB[3] = {-150, 0, -0.5};
- static float pntABA[3] = {-140, 0, -0.5};
- static float pntABB[3] = {-120, 0, -0.5};
- static float pntBAA[3] = {-100, 0, -0.5};
- static float pntBAB[3] = {-80, 0, -0.5};
- static float pntBBA[3] = {-70, 0, -0.5};
- static float zrot = 0.0;
- static float dzrot = 0.0;
- static int stenciling = 0;
- static int depthtest = 1;
- static int alwayspass = 0;
- static int depthMask = 0;
-
- static void SetUpColorMap(void)
- {
- XColor *xc;
- float color;
- long i, j, cells;
-
- if (indexBits < 5) return;
-
- cells = 16;
- xc = (XColor *) malloc(cells * sizeof(XColor));
-
- for (i = 0; i < 16; i++) {
- xc[i].pixel = i + COLOR_OFFSET;
- xc[i].red = i * 4369;
- xc[i].green = i * 4369;
- xc[i].blue = 0;
- xc[i].flags = DoRed | DoGreen | DoBlue;
- }
- XStoreColors(dpy, cmap, xc, cells);
-
- free((void *) xc);
- }
-
- static void Init(void)
- {
- if (!rgb) {
- glGetIntegerv(GL_INDEX_BITS, &indexBits);
- SetUpColorMap();
- }
-
- mode1 = 0;
- mode2 = 0;
- size = 1;
-
- glViewport(10, 10, W-20, H-20);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-175, 175, -175, 175, -1, 1);
- glMatrixMode(GL_MODELVIEW);
-
- }
-
- static void Redraw(void)
- {
- long i;
-
- if (dzrot != 0.0) {
- zrot += dzrot;
- }
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glLineWidth(3);
- glDisable(GL_LINE_STIPPLE);
- glDisable(GL_LINE_SMOOTH);
- glDisable(GL_BLEND);
-
- if (depthtest) {
- glClearDepth(1.0);
- glClear(GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- if (alwayspass) {
- glDepthFunc(GL_ALWAYS);
- } else {
- glDepthFunc(GL_LESS);
- }
-
- SETCOLOR(MAGENTA);
- glBegin(GL_LINES);
- for (i = -8; i <= 8; i++) {
- glVertex3f(i*20, -175, 0);
- glVertex3f(i*20, 175, 0);
- }
- if (depthMask) {
- glEnd();
- glDepthMask(GL_FALSE);
- glBegin(GL_LINES);
- }
- for (i = -8; i <= 8; i++) {
- glVertex3f(-175, i*20, 0);
- glVertex3f( 175, i*20, 0);
- }
- glEnd();
- if (depthMask) {
- glDepthMask(GL_TRUE);
- }
- }
-
- if (stenciling) {
- SETCOLOR(BLACK);
-
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
-
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 1, 3);
- glStencilOp(GL_KEEP, GL_INVERT, GL_REPLACE);
-
- glBegin(GL_LINES);
- for (i = -10; i <= 10; i++) {
- glVertex3f(i*17, -175, -0.5);
- glVertex3f(i*17, 175, -0.5);
- }
- for (i = -10; i <= 10; i++) {
- glVertex3f(-175, i*17, -0.5);
- glVertex3f( 175, i*17, -0.5);
- }
- glEnd();
-
- glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
-
- if (depthtest) {
- SETCOLOR(RED);
- glStencilFunc(GL_EQUAL, 3, 3);
- glDisable(GL_DEPTH_TEST);
- glBegin(GL_QUADS);
- glVertex3f(-175, -175, -0.5);
- glVertex3f(-175, 175, -0.5);
- glVertex3f( 175, 175, -0.5);
- glVertex3f( 175, -175, -0.5);
- glEnd();
- glEnable(GL_DEPTH_TEST);
- }
-
- glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP);
- glStencilFunc(GL_NOTEQUAL, 1, 1);
- }
-
- glLineWidth(size);
- if (mode1) {
- glEnable(GL_LINE_STIPPLE);
- } else {
- glDisable(GL_LINE_STIPPLE);
- }
- glLineStipple(1, 0xF0E0);
-
- if (blending) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
- }
-
- if (mode2) {
- glEnable(GL_LINE_SMOOTH);
- if (mode2 > 1) {
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- } else {
- glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
- }
- } else {
- glDisable(GL_LINE_SMOOTH);
- }
-
- glPushMatrix();
- glRotatef(zrot, 0,0,1);
- for (i = 0; i < 360; i += 5) {
- glRotatef(5.0, 0,0,1);
-
- if (rgb) glColor3fv(rgbMap[YELLOW]); else glIndexi(ci);
- glBegin(GL_LINE_STRIP);
- if (fragment) {
- glVertex3fv(pntA);
- glVertex3fv(pntAAB);
- glVertex3fv(pntABA);
- glVertex3fv(pntABB);
- if (rgb || !mode2) {
- SETCOLOR(CYAN);
- }
- glVertex3fv(pntBAA);
- glVertex3fv(pntBAB);
- glVertex3fv(pntBBA);
- glVertex3fv(pntB);
- } else {
- glVertex3fv(pntA);
- if (rgb || !mode2) {
- SETCOLOR(CYAN);
- }
- glVertex3fv(pntB);
- }
- glEnd();
-
- SETCOLOR(GREEN);
- }
- glPopMatrix();
-
- glFlush();
-
- if (depthtest) {
- glDisable(GL_DEPTH_TEST);
-
- if (stenciling) {
- SETCOLOR(WHITE);
- glStencilFunc(GL_EQUAL, 3, 3);
- glBegin(GL_QUADS);
- glVertex3f(-175, -175, -0.5);
- glVertex3f(-175, 175, -0.5);
- glVertex3f( 175, 175, -0.5);
- glVertex3f( 175, -175, -0.5);
- glEnd();
- }
- }
-
- if (stenciling) {
- glDisable(GL_STENCIL_TEST);
- }
-
- if (doubleBuf) {
- glXSwapBuffers(dpy, window);
- }
- }
-
- static void Usage(void)
- {
- fprintf(stderr, "Usage: program [-c] [-s] [-geometry WxH+X+Y]\n");
- fprintf(stderr, " -c run in color index mode\n");
- fprintf(stderr, " -s run in singlebuffer mode\n");
- fprintf(stderr, " -geometry window size and location\n");
- exit(1);
- }
-
- static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
- {
- if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
- return GL_TRUE;
- }
- return GL_FALSE;
- }
-
- int main(int argc, char** argv)
- {
- XVisualInfo *vi;
- XSetWindowAttributes swa;
- GLXContext cx;
- XEvent event;
- GLboolean needDisplay;
- XColor black;
- int i;
- XSizeHints sizehints;
- char *geometry = NULL;
-
- rgb = 1;
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- if (strcmp(argv[i], "-geometry") == 0) {
- i++;
- geometry = argv[i];
- } else switch (argv[i][1]) {
- case 'c':
- rgb = GL_FALSE;
- break;
- case 's':
- doubleBuf = 0;
- break;
- default:
- Usage();
- }
- } else {
- Usage();
- }
- }
-
- dpy = XOpenDisplay(0);
- if (!dpy) {
- fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
- return -1;
- }
-
- vi = glXChooseVisual(dpy, DefaultScreen(dpy),
- doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
- (rgb ? RGB_SB_attributes : CI_SB_attributes));
- if (!vi) {
- fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
- getenv("DISPLAY"));
- return -1;
- }
-
- sizehints.flags = PPosition | PSize;
- sizehints.width = W;
- sizehints.height = H;
- sizehints.x = 10;
- sizehints.y = 10;
- if(geometry) {
- int flags, x, y, width, height;
-
- flags = XParseGeometry(geometry, &x, &y,
- (unsigned int *)&width,
- (unsigned int *)&height);
- if(WidthValue & flags) {
- sizehints.flags |= USSize;
- sizehints.width = width;
- W = width;
- }
- if(HeightValue & flags) {
- sizehints.flags |= USSize;
- sizehints.height = height;
- H = height;
- }
- if(XValue & flags) {
- if(XNegative & flags)
- x = DisplayWidth(dpy, DefaultScreen(dpy)) + x
- - sizehints.width;
- sizehints.flags |= USPosition;
- sizehints.x = x;
- }
- if(YValue & flags) {
- if(YNegative & flags)
- y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
- - sizehints.height;
- sizehints.flags |= USPosition;
- sizehints.y = y;
- }
- }
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
- rgb ? AllocNone : AllocAll);
-
- if (!rgb) {
- XColor buf;
- int i;
-
- buf.flags = DoRed | DoGreen | DoBlue;
-
- /* Init color map */
- for (i=0; i<16; i++) {
- buf.pixel = i;
- buf.blue = (i & 4) ? 65535 : 0;
- buf.green = (i & 2) ? 65535 : 0;
- buf.red = (i & 1) ? 65535 : 0;
- if (i > 8) {
- buf.red /= 2;
- buf.green /= 2;
- buf.blue /= 2;
- }
- XStoreColor(dpy, cmap, &buf);
- }
- }
-
- swa.border_pixel = 0;
- swa.background_pixmap = None;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
- | KeyReleaseMask;
- window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
- sizehints.x, sizehints.y,
- sizehints.width, sizehints.height,
- 0, vi->depth, InputOutput, vi->visual,
- CWBackPixmap|CWBorderPixel|CWColormap|CWEventMask,
- &swa);
- XSetStandardProperties(dpy, window, "tline", "tline", None,
- argv, argc, &sizehints);
- XSetWMColormapWindows(dpy, window, &window, 1);
- XMapWindow(dpy, window);
- XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
-
- cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
- if (!glXMakeCurrent(dpy, window, cx)) {
- fprintf(stderr, "Can't make window current to context\n");
- return -1;
- }
-
- Init();
-
- needDisplay = GL_TRUE;
- for (;;) {
- if (XPending(dpy) || dzrot == 0.0) do {
- XNextEvent(dpy, &event);
- switch (event.type) {
- case Expose:
- needDisplay = GL_TRUE;
- break;
- case ConfigureNotify:
- W = event.xconfigure.width;
- H = event.xconfigure.height;
- glViewport(10, 10, W-20, H-20);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-175, 175, -175, 175, -1, 1);
- glMatrixMode(GL_MODELVIEW);
- needDisplay = GL_TRUE;
- break;
- case KeyPress:
- {
- char buf[100];
- int rv;
- KeySym ks;
- GLboolean setNeed = GL_TRUE;
-
- rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
- switch (ks) {
- case XK_Escape:
- exit(0);
- case XK_Y:
- case XK_y:
- blending = 1-blending;
- break;
- case XK_G:
- case XK_g:
- if (dzrot != 0.0) {
- dzrot = 0.0;
- } else {
- dzrot = 0.2;
- }
- break;
- case XK_q:
- case XK_Q:
- mode1 = 1;
- break;
- case XK_w:
- case XK_W:
- mode1 = 0;
- break;
- case XK_e:
- case XK_E:
- mode2 = 2;
- ci = COLOR_OFFSET;
- break;
- case XK_r:
- case XK_R:
- mode2 = 1;
- ci = COLOR_OFFSET;
- break;
- case XK_t:
- case XK_T:
- mode2 = 0;
- ci = YELLOW;
- break;
- case XK_a:
- case XK_A:
- if (mode2) {
- size += 0.25;
- } else {
- size ++;
- }
- break;
- case XK_z:
- case XK_Z:
- if (mode2) {
- size -= 0.25;
- } else {
- size --;
- }
- if (size < 1) {
- size = 1;
- }
- break;
- case XK_D:
- case XK_d:
- dither = !dither;
- if (dither) {
- glEnable(GL_DITHER);
- printf("Dithering on\n");
- } else {
- glDisable(GL_DITHER);
- printf("Dithering off\n");
- }
- break;
- case XK_F:
- case XK_f:
- fragment = !fragment;
- if (fragment) {
- printf("Fragmenting\n");
- } else {
- printf("No fragmenting\n");
- }
- break;
- case XK_S:
- case XK_s:
- smoothModel = !smoothModel;
- if (smoothModel) {
- printf("Smooth shading\n");
- glShadeModel(GL_SMOOTH);
- } else {
- printf("Flat shading\n");
- glShadeModel(GL_FLAT);
- }
- break;
- case XK_X:
- case XK_x:
- stenciling = !stenciling;
- if (stenciling) {
- printf("Stenciling\n");
- } else {
- printf("Not stenciling\n");
- }
- break;
- case XK_C:
- case XK_c:
- depthtest = !depthtest;
- if (depthtest) {
- printf("Depth testing\n");
- } else {
- printf("No depth testing\n");
- }
- break;
- case XK_V:
- case XK_v:
- alwayspass = !alwayspass;
- if (alwayspass) {
- printf("Always pass\n");
- } else {
- printf("Not always pass\n");
- }
- break;
- case XK_B:
- case XK_b:
- depthMask = !depthMask;
- if (depthMask) {
- printf("Depth writes masked for horizontal lines\n");
- } else {
- printf("Depth writes not masked\n");
- }
- break;
- default:
- setNeed = GL_FALSE;
- break;
- }
- if (setNeed) needDisplay = GL_TRUE;
- }
- break;
- }
- } while (XPending(dpy) != 0);
-
- if (dzrot != 0.0 || needDisplay) {
- needDisplay = GL_FALSE;
- Redraw();
- }
- }
- }
-